#include <fst/symbol-table.h>
#include <fst/script/fstscript.h>

#ifdef _MSC_VER
	#define FSTX_DLLEXPORT __declspec(dllexport)
#else
	#define FSTX_DLLEXPORT 
#endif

using fst::script::FstClass;
using fst::script::VectorFstClass;

using fst::SymbolTable;
using namespace fst::script;

extern "C" 
{
	FSTX_DLLEXPORT FstClass* ReadFst(const char* path) {
		return FstClass::Read(path);
	}

	FSTX_DLLEXPORT void WriteFst(FstClass* fst, const char* path) {
		fst->Write(path);
	}

	FSTX_DLLEXPORT FstClass* CreateFst(const char* arc_type) {		
		return new fst::script::VectorFstClass(arc_type);
	}

	FSTX_DLLEXPORT const char*  ArcType(FstClass* fst) {		
		return fst->ArcType().c_str();
	}

	FSTX_DLLEXPORT const char* FstType(FstClass* fst) {
		return fst->FstType().c_str();
	}

	FSTX_DLLEXPORT void FreeFst(FstClass* fst) {
		if (fst != NULL)
			delete fst;
	}

	//How best to handle the destructive operations that can 
	//accept an FstClass or VectorFstClass
	FSTX_DLLEXPORT FstClass* ArcSort(FstClass* fst, const char* sort_type) {
		ArcSortType st = ILABEL_COMPARE;
		VectorFstClass* ofst = new VectorFstClass(*fst);
		fst::script::ArcSort(ofst, st);
		return ofst;
	}

	FSTX_DLLEXPORT FstClass* Compose(FstClass* fst1, FstClass* fst2) {
		//TODO: Arc type checks
		VectorFstClass* ofst = new  VectorFstClass(fst1->ArcType());
		fst::script::Compose(*fst1, *fst2, ofst);
		return ofst;
	}

	FSTX_DLLEXPORT FstClass* Determinize(FstClass* fst) {
		VectorFstClass* ofst = new  VectorFstClass(fst->ArcType());
		fst::script::Determinize(*fst, ofst);		
		return ofst;
	}
	
	FSTX_DLLEXPORT SymbolTable* CreateSymbolTable(const char* name) {
		return new SymbolTable(name);
	}

	FSTX_DLLEXPORT void FreeSymbolTable(SymbolTable* syms) {
		delete syms;
	}

	FSTX_DLLEXPORT SymbolTable* ReadText(const char* filename) {
		return SymbolTable::ReadText(filename);
	}	
}